package cn.itcast.demo;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.File;
import java.io.IOException;

public class TestIndexQuerySuper {


    @Test
    public void testHighLightQuery() throws IOException, ParseException, InvalidTokenOffsetsException {
        //Directory 访问目录对象
        Directory directory = FSDirectory.open(new File("indexDir"));

        //需要一个对象进行io操作把目录对象中的内容读取出来
        //indexReader也应该实现动态
        IndexReader indexReader = DirectoryReader.open(directory);


        //创建索引的搜索对象
        IndexSearcher searcher = new IndexSearcher(indexReader);


        QueryParser queryParser = new QueryParser("title", new IKAnalyzer());

        Query query = queryParser.parse("facebook");


        //query表示查询条件对象，n表示用户最大期待的数据的量（如果匹配的量大于这个数字，则取前n条）
        //topDocs表示查询到的前n个文档的集合
        TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE);

        //本次查询命中的个数
        int totalHits = topDocs.totalHits;

        System.out.println("命中了： " + totalHits);

        //查询到的文档的集合数组
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        //准备高亮的工具

        //创建html的格式化工具
        Formatter formatter = new SimpleHTMLFormatter("<em>", "</em>");

        Scorer scorer = new QueryScorer(query);
        Highlighter highlighter = new Highlighter(formatter, scorer);

        for (ScoreDoc scoreDoc : scoreDocs) {
            //获取文档的得分
            float score = scoreDoc.score;

            //获取文档的编号
            int doc = scoreDoc.doc;

            //根据文档编号获取文档
            Document document = searcher.doc(doc);

            String id = document.get("id");
            //普通查询的结果
            String titleResult = document.get("title");

            //使用高亮工具对title进行高亮操作，二次分词
            String highlighterTitle = highlighter.getBestFragment(new IKAnalyzer(), "title", titleResult);

            System.out.println("score: " + score + " id:" + id + " title:" + highlighterTitle);

        }

    }


    //查询排序
    @Test
    public void testSortQuery() throws IOException, ParseException, InvalidTokenOffsetsException {
        //Directory 访问目录对象
        Directory directory = FSDirectory.open(new File("indexDir"));

        //需要一个对象进行io操作把目录对象中的内容读取出来
        //indexReader也应该实现动态
        IndexReader indexReader = DirectoryReader.open(directory);


        //创建索引的搜索对象
        IndexSearcher searcher = new IndexSearcher(indexReader);


        QueryParser queryParser = new QueryParser("title", new IKAnalyzer());

        Query query = queryParser.parse("facebook");


        //创建排序条件,SortField中可以加三个参数，第一个表示排序的字段，第二个表示字段类型，第三个可选，表示升序还是降序
        Sort sort = new Sort(new SortField("id", SortField.Type.LONG));

        //query表示查询条件对象，n表示用户最大期待的数据的量（如果匹配的量大于这个数字，则取前n条）
        //topDocs表示查询到的前n个文档的集合

        TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE, sort);

        //本次查询命中的个数
        int totalHits = topDocs.totalHits;

        System.out.println("命中了： " + totalHits);

        //查询到的文档的集合数组
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;


        for (ScoreDoc scoreDoc : scoreDocs) {
            //获取文档的得分
            float score = scoreDoc.score;

            //获取文档的编号
            int doc = scoreDoc.doc;

            //根据文档编号获取文档
            Document document = searcher.doc(doc);

            String id = document.get("id");
            //普通查询的结果
            String titleResult = document.get("title");

            System.out.println("score: " + score + " id:" + id + " title:" + titleResult);

        }

    }


    //分页查询，不支持物理分页，limit，逻辑分页，效率问题，把所有的数据都查询出来，然后进行分页操作
    //100万------》10条
    @Test
    public void testPageQuery() throws IOException, ParseException, InvalidTokenOffsetsException {


        int currentPage = 4;

        final int PAGE_SIZE = 2;

        int start = (currentPage - 1) * PAGE_SIZE;

        int end = currentPage * PAGE_SIZE;


        //Directory 访问目录对象
        Directory directory = FSDirectory.open(new File("indexDir"));

        //需要一个对象进行io操作把目录对象中的内容读取出来
        //indexReader也应该实现动态
        IndexReader indexReader = DirectoryReader.open(directory);


        //创建索引的搜索对象
        IndexSearcher searcher = new IndexSearcher(indexReader);


        QueryParser queryParser = new QueryParser("title", new IKAnalyzer());

        Query query = queryParser.parse("facebook");


        //创建排序条件,SortField中可以加三个参数，第一个表示排序的字段，第二个表示字段类型，第三个可选，表示升序还是降序
        Sort sort = new Sort(new SortField("id", SortField.Type.LONG));

        //query表示查询条件对象，n表示用户最大期待的数据的量（如果匹配的量大于这个数字，则取前n条）
        //topDocs表示查询到的前n个文档的集合

        TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE, sort);

        //本次查询命中的个数
        int totalHits = topDocs.totalHits;

        System.out.println("命中了： " + totalHits);

        //查询到的文档的集合数组
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        //加两个变量来判断

        int total = scoreDocs.length;

        int totalPage = total % PAGE_SIZE == 0 ? total / PAGE_SIZE : total / PAGE_SIZE + 1;


        if (currentPage>totalPage){
            System.out.println("没那么多页展示");
            return;
        }else if (currentPage==totalPage){//最后一页，满页，符合算法，不满页，end应该就是total

            end = total;
        }


        for (int i = start; i < end; i++) {
            ScoreDoc scoreDoc = scoreDocs[i];

            //获取文档的得分
            float score = scoreDoc.score;

            //获取文档的编号
            int doc = scoreDoc.doc;

            //根据文档编号获取文档
            Document document = searcher.doc(doc);

            String id = document.get("id");
            //普通查询的结果
            String titleResult = document.get("title");

            System.out.println("score: " + score + " id:" + id + " title:" + titleResult);
        }


    }
}
